﻿using System.Collections.Generic;
using Map;
using Map_Creator.MapInfo;
using Microsoft.Xna.Framework;

namespace Map_Creator.RedoUndo.Actions
{
    class TilePaintAction :IAction
    {
        private TileStructGrid sourceGrid;
        private int destLayerID;
        private Rectangle sourceRect;
        private Dictionary<Rectangle, CopyGrid> destRectOldGrid; 

        public TilePaintAction(TileStructGrid sourceGrid, Layer destLayer, Rectangle sourceRect, List<Rectangle> destRects)
        {
            this.sourceGrid = sourceGrid;
            this.destLayerID = destLayer.ID;
            this.sourceRect = sourceRect;
            this.destRectOldGrid = new Dictionary<Rectangle, CopyGrid>();

            foreach (var destRect in destRects)
            {
                destRectOldGrid.Add(destRect,CopyGrid.Copy(destLayer.data, destRect));
            }
        }

        public TilePaintAction(TileStructGrid sourceGrid, Layer destLayer, Rectangle sourceRect, Rectangle destRect)
            : this(sourceGrid,destLayer,sourceRect, new List<Rectangle>{destRect})
        {
            
        }

        public TilePaintAction(TileStructGrid sourceGrid,  Layer destLayer, List<Rectangle> destRects)
            : this(sourceGrid, destLayer, new Rectangle(0, 0, sourceGrid.Size.X, sourceGrid.Size.Y), destRects)
        {
        }

        public TilePaintAction(TileStructGrid sourceGrid,  Layer destLayer, Rectangle destRect)
            : this(sourceGrid, destLayer, new List<Rectangle> { destRect })
        {
            
        }

        public void AddSingleDestAndExecute(Rectangle destRect)
        {
            var destGrid = ((Layer)BaseObject.Objects[destLayerID]).data;
            if (destRectOldGrid.ContainsKey(destRect))
                return;
            destRectOldGrid.Add(destRect,CopyGrid.Copy(destGrid, destRect));
            PaintTiles(destGrid,destRect);
        }

        public void Do()
        {
            var destGrid = ((Layer)BaseObject.Objects[destLayerID]).data;
            foreach (var pair in destRectOldGrid)
            {
                var destRect = pair.Key;
                PaintTiles(destGrid, destRect);
            }
        }

        private void PaintTiles(TileStructGrid destGrid, Rectangle destRect)
        {
            for (var i = 0; i < destRect.Width; i++)
            {
                for (var j = 0; j < destRect.Height; j++)
                {
                    var tile = sourceGrid[i%sourceRect.Width + sourceRect.X, j%sourceRect.Height + sourceRect.Y];
                    var pos = new Point(destRect.Left + i, destRect.Top + j);
                    destGrid[pos.X, pos.Y] = tile;
                    if (tile != null)
                    {
                        (tile).UpdateValue(destGrid, pos);
                    }
                }
            }
        }

        public void Undo()
        {
            var destGrid = ((Layer)BaseObject.Objects[destLayerID]).data;
            foreach (var pair in destRectOldGrid)
            {
                pair.Value.Paste(destGrid, pair.Key);
            }
        }

        public string GetDescription()
        {
            return "Paint Lots Of Tiles... I Think";
        }

        public string GetName()
        {
            return "Paint Tiles";
        }
    }
}
